package model

import (
	"gowork/makeAnAppointment/utils"
	"sync"
	"time"
)

type Professor struct {
	Id int64 `xorm:"pk autoincr"`
	DepartmentId int64
	DepartmentName string
	Name string
	ProfessionalDirection string
	AvailableAppointmentList []*AvailableAppointment `xorm:"-"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

type AvailableAppointment struct {
	Id int64 `xorm:"pk autoincr"`
	ProfessorId int64
	ProfessorName string
	VisitOutTime string
	MedicalExpenses int
	WhetherToBeBooked int
	SignNumber int
	CreatedAt time.Time
	UpdatedAt time.Time
}

type AppointmentRecord struct {
	Id int64 `xorm:"pk autoincr"`
	ProfessorId int64
	ProfessorName string
	VisitInTime string
	MedicalExpenses int
	AppointmentPersonId int64
	AppointmentPersonName string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type Dateable struct {
	Name string
	AvailableAppointmentList []*AvailableAppointment
	ProfessorList []*Professor
}

func GetMonth(m string) int{
	switch m {
	case "January":
		return 1
	case "February":
		return 2
	case "March":
		return 3
	case "April":
		return 4
	case "May":
		return 5
	case "June":
		return 6
	case "July":
		return 7
	case "August":
		return 8
	case "September":
		return 9
	case "October":
		return 10
	case "November":
		return 11
	case "December":
		return 12
	}
	return 0
}

func (availableAppointment *AvailableAppointment)SetUpAppointments(dList []string, tseList []string, pList []*Professor, sn int, me int)(map[string]interface{}, error){

	w := new(utils.Worker)

	for _, dv := range dList{
		for _, tsev := range tseList{
			for _, pv := range pList {
				var aa AvailableAppointment
				aa.Id = w.GetId()
				aa.ProfessorId = pv.Id
				aa.ProfessorName = pv.Name
				aa.VisitOutTime = dv + " " + tsev   //  tsev = "09:00 - 12:00"
				aa.MedicalExpenses = me
				aa.WhetherToBeBooked = 1
				aa.SignNumber = sn
				aa.CreatedAt = time.Now()
				aa.UpdatedAt = time.Now()
				x.Insert(&aa)
			}
		}
	}
	return map[string]interface{}{"message": "成功","code":200}, nil
}

func (availableAppointment *AvailableAppointment)QueryAppointmentAvailable(dId int64)([]*Dateable, error){

	var dateableList []*Dateable

	var count int = 0
	for {
		if len(dateableList) == 7{
			break
		}

		cTime := time.Now().AddDate(0,0,count)

		var db Dateable
		db.Name = cTime.Format("2006-01-02")
		dateableList = append(dateableList, &db)

		count += 1
	}

	for _, d := range dateableList{
		x.Join("INNER", "professor", "professor.id = available_appointment.professor_id").
			Where("professor.department_id = ?", dId).
			And("available_appointment.visit_out_time like ?", d.Name+"%").
			Find(&d.AvailableAppointmentList)
	}

	return dateableList, nil
}

func (availableAppointment *AvailableAppointment)QueryAppointmentAvailableNew(dId int64)([]*Dateable, error){

	var dateableList []*Dateable

	var count int = 0
	for {
		if len(dateableList) == 7{
			break
		}

		cTime := time.Now().AddDate(0,0,count)

		var db Dateable
		db.Name = cTime.Format("2006-01-02")
		dateableList = append(dateableList, &db)

		count += 1
	}

	for _, d := range dateableList{
		x.Join("INNER", "available_appointment", "available_appointment.professor_id = professor.id").
			Where("available_appointment.visit_out_time like ?", d.Name+"%").
			And("professor.department_id = ?", dId).
			Find(&d.ProfessorList)

		for _, p := range d.ProfessorList{
			x.Where("professor_id = ?", p.Id).
				Find(&p.AvailableAppointmentList)
		}
	}

	return dateableList, nil
}

var lock sync.Mutex

func (availableAppointment *AvailableAppointment)UserAppointment(uId int64, uName string, aaId int64)(map[string]interface{}, error){

	lock.Lock()

	w := new(utils.Worker)

	var aav AvailableAppointment
	x.Where("id = ?", aaId).Get(&aav)

	if aav.SignNumber == 1{

		lock.Unlock()

		return map[string]interface{}{"message": "该预约已满","code":400}, nil
	}

	var ar AppointmentRecord
	ar.Id = w.GetId()
	ar.ProfessorId = aav.ProfessorId
	ar.ProfessorName = aav.ProfessorName
	ar.VisitInTime = aav.VisitOutTime
	ar.MedicalExpenses = aav.MedicalExpenses
	ar.AppointmentPersonId = uId
	ar.AppointmentPersonName = uName
	ar.CreatedAt = time.Now()
	ar.UpdatedAt = time.Now()
	x.Insert(&ar)

	aav.SignNumber -= 1
	x.Id(aav.Id).Update(&aav)

	if aav.SignNumber == 0 {
		aav.WhetherToBeBooked = 2
		x.Id(aav.Id).Update(&aav)
	}

	lock.Unlock()

	return map[string]interface{}{"message": "成功","code":200}, nil
}
